// ----------------------------------
// RSDK Project: Sonic 2
// Script Description: Text Message Object
// Script Author: Christian Whitehead/Simon Thomley
// Unpacked by Rubberduckycooly's script unpacker
// ----------------------------------

// ========================
// Aliases
// ========================

private alias object.value0 : object.timer
private alias object.value1 : object.textMessage
private alias object.value2 : object.charPos.x
private alias object.value3 : object.messageLength
private alias object.value4 : object.number
private alias object.value5 : object.angleOffset
private alias object.value6 : object.scaleSpeed
private alias object.value7 : object.rotateSpeed
private alias object.value8 : object.spinDirection

// Property Values
private alias 0 : TEXTMESSAGE_COOL
private alias 1 : TEXTMESSAGE_NOTENOUGH
private alias 2 : TEXTMESSAGE_GETRINGS
private alias 3 : TEXTMESSAGE_RINGREMINDER
private alias 4 : TEXTMESSAGE_PLAYERPLAYER
private alias 5 : TEXTMESSAGE_MOSTRINGSWIN
private alias 6 : TEXTMESSAGE_P1WINS
private alias 7 : TEXTMESSAGE_P2WINS
private alias 8 : TEXTMESSAGE_TIE
private alias 9 : TEXTMESSAGE_ANICHARACTER

// Messages
private alias 0  : MESSAGE_COOL
private alias 1  : MESSAGE_NOTENOUGH
private alias 2  : MESSAGE_RINGS
private alias 3  : MESSAGE_GETRINGS1
private alias 4  : MESSAGE_GETRINGS2
private alias 5  : MESSAGE_GETRINGS3
private alias 6  : MESSAGE_RINGTOGO
private alias 7  : MESSAGE_RINGSTOGO1
private alias 8  : MESSAGE_RINGSTOGO2
private alias 9  : MESSAGE_RINGSTOGO3
private alias 10 : MESSAGE_PLAYERPLAYER
private alias 11 : MESSAGE_MOSTRINGSWINS
private alias 12 : MESSAGE_P1WINS
private alias 13 : MESSAGE_P2WINS
private alias 14 : MESSAGE_TIE

// Player Aliases
private alias object.value0 : player.rings

// Text Menu Info Type Aliases
private alias 0 : TEXTINFO_TEXTDATA
private alias 1 : TEXTINFO_TEXTSIZE


// ========================
// Function Declarations
// ========================

reserve function TextMessage_DrawMessage
reserve function TextMessage_SetupTextChars


// ========================
// Function Definitions
// ========================

private function TextMessage_DrawMessage
	// This function is called to *draw* a line of text
	
	GetTextInfo(object.messageLength, MENU_1, TEXTINFO_TEXTSIZE, object.textMessage, 0)

	object.charPos.x = object.messageLength
	object.charPos.x <<= 2
	FlipSign(object.charPos.x)
	object.charPos.x += screen.xcenter
	object.charPos.x += 4

	temp0 = 0
	while object.messageLength > 0
		GetTextInfo(temp1, MENU_1, TEXTINFO_TEXTDATA, object.textMessage, temp0)
		switch temp1
		case 33 // !
			DrawSpriteScreenXY(37, object.charPos.x, object.ypos)
			object.charPos.x += 8
			break

		case 35 // #
			temp2 = object.number
			temp2 /= 100
			DrawSpriteScreenXY(temp2, object.charPos.x, object.ypos)
			object.charPos.x += 8
			break

		case 36 // $
			temp2 = object.number
			temp2 %= 100
			temp2 /= 10
			DrawSpriteScreenXY(temp2, object.charPos.x, object.ypos)
			object.charPos.x += 8
			break

		case 37 // %
			temp2 = object.number
			temp2 %= 10
			DrawSpriteScreenXY(temp2, object.charPos.x, object.ypos)
			object.charPos.x += 8
			break

		case 38 // &
			DrawSpriteScreenXY(38, object.charPos.x, object.ypos)
			object.charPos.x += 8
			break

		case 46 // .
			DrawSpriteScreenXY(36, object.charPos.x, object.ypos)
			object.charPos.x += 8
			break

		default
			object.frame = 0
			
			// Translate uppercase letters to Sprite Frames
			if temp1 > 64
				if temp1 < 91
					object.frame = temp1
					object.frame -= 55
				end if
			end if
			
			// Translate lowercase letters to Sprite Frames
			if temp1 > 96
				if temp1 < 123
					object.frame = temp1
					object.frame -= 87
				end if
			end if
			
			if object.frame > 0
				DrawSpriteScreenXY(object.frame, object.charPos.x, object.ypos)
			end if
			
			object.charPos.x += 8
			break
			
		end switch
		
		temp0++
		object.messageLength--
	loop
end function


private function TextMessage_SetupTextChars
	// This function is called to create letter objects for every individual letter in a line, for when the message should separate and fall apart
	// This is not to be confused with actually drawing the text normally, that's up above
	
	GetTextInfo(object.messageLength, MENU_1, TEXTINFO_TEXTSIZE, object.textMessage, 0)

	object.charPos.x = object.messageLength
	object.charPos.x <<= 2
	FlipSign(object.charPos.x)
	object.charPos.x += 4
	object.charPos.x <<= 16

	temp0 = 0
	temp3 = object.ypos
	temp3 <<= 16
	object.angleOffset = 224
	object.angleOffset /= object.messageLength
	while object.messageLength > 0
		GetTextInfo(temp1, MENU_1, TEXTINFO_TEXTDATA, object.textMessage, temp0)
		object.frame = 255

		switch temp1
		case 33 // !
			object.frame = 37
			break

		case 35 // #
			temp2 = object.number
			temp2 /= 100
			object.frame = temp2
			break

		case 36 // $
			temp2 = object.number
			temp2 %= 100
			temp2 /= 10
			object.frame = temp2
			break

		case 37 // %
			temp2 = object.number
			temp2 %= 10
			object.frame = temp2
			break

		case 38 // &
			object.frame = 38
			break

		case 46 // .
			object.frame = 36
			break

		default
			if temp1 > 64
				if temp1 < 91
					object.frame = temp1
					object.frame -= 55
				end if
			end if
			
			if temp1 > 96
				if temp1 < 123
					object.frame = temp1
					object.frame -= 87
				end if
			end if
			break
			
		end switch

		if object.frame < 255
			CreateTempObject(TypeName[Text Message], TEXTMESSAGE_ANICHARACTER, object.charPos.x, temp3)
#platform: USE_STANDALONE
			object[tempObjectPos].drawOrder = 5
#endplatform
#platform: USE_ORIGINS
			object[tempObjectPos].drawOrder = 6
#endplatform
			object[tempObjectPos].frame = object.frame

			if object.spinDirection == 0
				object[tempObjectPos].angle = object.angle
			else
				object[tempObjectPos].angle = object.angle
				FlipSign(object[tempObjectPos].angle)
				object[tempObjectPos].angle += 0x100
				object[tempObjectPos].angle &= 0x1FF
			end if

			object[tempObjectPos].speed = -0x10000
			object[tempObjectPos].scaleSpeed = 16
			Rand(object[tempObjectPos].rotateSpeed, 32)
			object[tempObjectPos].rotateSpeed -= 16
		end if

		object.angle -= object.angleOffset
		object.angle &= 0x1FF
		object.charPos.x += 0x80000
		temp0++
		object.messageLength--
	loop
end function


// ========================
// Events
// ========================

event ObjectUpdate
	switch object.propertyValue
	case TEXTMESSAGE_COOL
	case TEXTMESSAGE_PLAYERPLAYER
		if object.timer < 120
			object.timer++
		else
			object.angle = 96
			CallFunction(TextMessage_SetupTextChars)
			ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
		end if
		break

	case TEXTMESSAGE_NOTENOUGH
		if object.timer < 120
			object.timer++
		else
			object.spinDirection = 0
			object.textMessage = MESSAGE_NOTENOUGH
			object.ypos = 116
			object.angle = 96
			CallFunction(TextMessage_SetupTextChars)

			object.spinDirection = 1
			object.ypos += 22
			object.textMessage = MESSAGE_RINGS
			object.angle = 96
			CallFunction(TextMessage_SetupTextChars)

			ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
		end if
		break

	case TEXTMESSAGE_GETRINGS
	case TEXTMESSAGE_MOSTRINGSWIN
		if object.timer < 90
			object.timer++
		else
			object.angle = 96
			CallFunction(TextMessage_SetupTextChars)
			ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
		end if
		break

	case TEXTMESSAGE_RINGREMINDER
		if stage.player2Enabled == true
			temp0 = player[2].rings
			temp0 += player[3].rings
		else
			temp0 = player[2].rings
		end if

		GetTableValue(temp1, SpecialSetup_checkpointID, SpecialSetup_ringCountTable)
		if temp0 < temp1
			object.animationTimer = 0
		else
			if object.animationTimer < 30
				object.animationTimer++
			end if
		end if

		CheckLower(temp0, temp1)
		temp2 = checkResult
		CheckLower(object.animationTimer, 30)
		temp2 |= checkResult
		if temp2 == true
			GetBit(object.visible, object.timer, 2)
			object.timer++
			object.timer &= 7
			object.number = temp1
			object.number -= temp0
			if object.number < 0
				object.number = 0
			end if
		else
			object.visible = false
		end if
		break

	case TEXTMESSAGE_P1WINS
	case TEXTMESSAGE_P2WINS
	case TEXTMESSAGE_TIE
		if object.timer < 90
			object.timer++
		else
			object.angle = 96
			CallFunction(TextMessage_SetupTextChars)
			ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
			if SpecialSetup_checkpointID < 3
				player[2].rings = 0
				player[3].rings = 0
			end if
		end if
		break

	case TEXTMESSAGE_ANICHARACTER
		object.xpos += object.xvel
		object.ypos += object.yvel
		object.scale += object.scaleSpeed
		object.rotation += object.rotateSpeed
		object.rotation &= 0x1FF
		object.speed -= 0x8000
		object.scaleSpeed++

		Cos(object.yvel, object.angle)
		object.yvel *= object.speed
		object.yvel >>= 9

		Sin(object.xvel, object.angle)
		object.xvel *= object.speed
		object.xvel >>= 9

		if object.timer < 120
			object.timer++
		else
			object.type = TypeName[Blank Object]
		end if
		break
		
	end switch
end event


event ObjectDraw
	switch object.propertyValue
	case TEXTMESSAGE_COOL
		object.ypos = 116
		object.textMessage = MESSAGE_COOL
		CallFunction(TextMessage_DrawMessage)
		break

	case TEXTMESSAGE_NOTENOUGH
		object.textMessage = MESSAGE_NOTENOUGH
		object.ypos = 116
		CallFunction(TextMessage_DrawMessage)

		object.ypos += 22
		object.textMessage = MESSAGE_RINGS
		CallFunction(TextMessage_DrawMessage)
		break

	case TEXTMESSAGE_GETRINGS
		object.ypos = 116
		if object.number > 99
			object.textMessage = MESSAGE_GETRINGS3
			CallFunction(TextMessage_DrawMessage)
		else
			if object.number > 9
				object.textMessage = MESSAGE_GETRINGS2
				CallFunction(TextMessage_DrawMessage)
			else
				object.textMessage = MESSAGE_GETRINGS1
				CallFunction(TextMessage_DrawMessage)
			end if
		end if
		break

	case TEXTMESSAGE_RINGREMINDER
		if object.visible == true
			object.ypos = 64
			if object.number > 99
				object.textMessage = MESSAGE_RINGSTOGO3
				CallFunction(TextMessage_DrawMessage)
			else
				if object.number > 9
					object.textMessage = MESSAGE_RINGSTOGO2
					CallFunction(TextMessage_DrawMessage)
				else
					if object.number == 1
						object.textMessage = MESSAGE_RINGTOGO
						CallFunction(TextMessage_DrawMessage)
					else
						object.textMessage = MESSAGE_RINGSTOGO1
						CallFunction(TextMessage_DrawMessage)
					end if
				end if
			end if
		end if
		break

	case TEXTMESSAGE_PLAYERPLAYER
		object.ypos = 116
		object.textMessage = MESSAGE_PLAYERPLAYER
		CallFunction(TextMessage_DrawMessage)
		break

	case TEXTMESSAGE_MOSTRINGSWIN
		object.ypos = 116
		object.textMessage = MESSAGE_MOSTRINGSWINS
		CallFunction(TextMessage_DrawMessage)
		break

	case TEXTMESSAGE_P1WINS
		object.ypos = 116
		object.textMessage = MESSAGE_P1WINS
		CallFunction(TextMessage_DrawMessage)
		break

	case TEXTMESSAGE_P2WINS
		object.ypos = 116
		object.textMessage = MESSAGE_P2WINS
		CallFunction(TextMessage_DrawMessage)
		break

	case TEXTMESSAGE_TIE
		object.ypos = 68
		object.textMessage = MESSAGE_TIE
		CallFunction(TextMessage_DrawMessage)
		break
		
	case TEXTMESSAGE_ANICHARACTER
		temp0 = object.xpos
		temp0 >>= 16
		temp0 += screen.xcenter

		temp1 = object.ypos
		temp1 >>= 16

		DrawSpriteScreenFX(object.frame, FX_ROTOZOOM, temp0, temp1)
		break
		
	end switch
end event


event ObjectStartup
	LoadSpriteSheet("Special/Objects.gif")
	
	// Here, we set up just about an entire font in Sprite Frames
	SpriteFrame(-4, -8, 8, 15, 291, 42) // 0
	SpriteFrame(-4, -8, 8, 15, 300, 42) // 1
	SpriteFrame(-4, -8, 8, 15, 309, 42) // 2
	SpriteFrame(-4, -8, 8, 15, 318, 42) // 3
	SpriteFrame(-4, -8, 8, 15, 327, 42) // 4
	SpriteFrame(-4, -8, 8, 15, 336, 42) // 5
	SpriteFrame(-4, -8, 8, 15, 345, 42) // 6
	SpriteFrame(-4, -8, 8, 15, 354, 42) // 7
	SpriteFrame(-4, -8, 8, 15, 363, 42) // 8
	SpriteFrame(-4, -8, 8, 15, 372, 42) // 9
	SpriteFrame(-4, -8, 8, 15, 291, 26) // A
	SpriteFrame(-4, -8, 8, 15, 300, 26) // B
	SpriteFrame(-4, -8, 8, 15, 309, 26) // C
	SpriteFrame(-4, -8, 8, 15, 318, 26) // D
	SpriteFrame(-4, -8, 8, 15, 327, 26) // E
	SpriteFrame(-4, -8, 8, 15, 336, 26) // F
	SpriteFrame(-4, -8, 8, 15, 345, 26) // G
	SpriteFrame(-4, -8, 8, 15, 354, 26) // H
	SpriteFrame(-4, -8, 8, 15, 363, 26) // I
	SpriteFrame(-4, -8, 8, 15, 372, 26) // J
	SpriteFrame(-4, -8, 8, 15, 381, 26) // K
	SpriteFrame(-4, -8, 8, 15, 390, 26) // L
	SpriteFrame(-4, -8, 8, 15, 399, 26) // M
	SpriteFrame(-4, -8, 8, 15, 408, 26) // N
	SpriteFrame(-4, -8, 8, 15, 417, 26) // O
	SpriteFrame(-4, -8, 8, 15, 426, 26) // P
	SpriteFrame(-4, -8, 8, 15, 435, 26) // Q
	SpriteFrame(-4, -8, 8, 15, 444, 26) // R
	SpriteFrame(-4, -8, 8, 15, 453, 26) // S
	SpriteFrame(-4, -8, 8, 15, 462, 26) // T
	SpriteFrame(-4, -8, 8, 16, 471, 26) // U
	SpriteFrame(-4, -8, 8, 15, 480, 26) // Supposed to be V, actually placeholder dash instead
	SpriteFrame(-4, -8, 8, 15, 381, 42) // W
	SpriteFrame(-4, -8, 8, 15, 390, 42) // Supposed to be X, actually placeholder dash instead
	SpriteFrame(-4, -8, 8, 15, 399, 42) // Y
	SpriteFrame(-4, -8, 8, 15, 408, 42) // Supposed to be Z, actually placeholder dash instead
	SpriteFrame(-4, -8, 8, 15, 489, 26) // . (Period)
	SpriteFrame(-4, -8, 8, 15, 498, 26) // ! (Exclamation mark)
	SpriteFrame(-12, -8, 24, 15, 417, 42) // VS yellow tag

	SetupMenu(MENU_1, 0, 3, 1)
	
	// Here, all the texts to be displayed are set up
	// The characters of #, $, and % are special, they display object.number's hundreds, tens, and ones place, respectively
	AddMenuEntry(MENU_1, "OTVNJHO!", false)
	AddMenuEntry(MENU_1, "HEDOCTATOJHO", false)
	AddMenuEntry(MENU_1, "KOVEQ ... ", false)
	AddMenuEntry(MENU_1, "COGEPN % KOVEQ!", false)
	AddMenuEntry(MENU_1, "COGEPN $% KOVEQ!", false)
	AddMenuEntry(MENU_1, "COGEPN #$% KOVEQ!", false)
	AddMenuEntry(MENU_1, "OCTAVOCW %!", false)
	AddMenuEntry(MENU_1, "OCTAVOCW %!", false)
	AddMenuEntry(MENU_1, "OCTAVOCW $%!", false)
	AddMenuEntry(MENU_1, "OCTAVOCW #$%!", false)
	AddMenuEntry(MENU_1, "NSPOK N NSPOK", false)
	AddMenuEntry(MENU_1, "COGNPAUTE KOVWQA!", false)
	AddMenuEntry(MENU_1, "1 NSPOK BWINSPWIBAET!", false)
	AddMenuEntry(MENU_1, "2 NSPOK BWINSPWIBAET!", false)
	AddMenuEntry(MENU_1, "HNJWR!", false)
end event


// ========================
// Editor Events
// ========================

event RSDKDraw
	DrawSprite(0)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Display.gif")
	SpriteFrame(-16, -16, 32, 32, 1, 143)
	
	SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
end event
